package com.zhu.day.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BatchThreadUtil {
    private static final Logger log = LoggerFactory.getLogger(BatchThreadUtil.class);

    public BatchThreadUtil() {
    }

    public static <T, R> List<R> multiGet(Collection<T> idList, Function<T, R> getFuc) {
        return multiGet(idList, ThreadExecuter.executor, 1000L, getFuc);
    }

    public static <T, R> List<R> multiGet(Collection<T> idList, ExecutorService executor, Function<T, R> getFuc) {
        return multiGet(idList, executor, 1000L, getFuc);
    }

    public static <T, R> List<R> multiGet(Collection<T> idList, ExecutorService executor, long timeout, Function<T, R> getFuc) {
        List<R> result = new ArrayList(idList.size());
        CompletionService<R> completionService = new ExecutorCompletionService(executor);
        Iterator var7 = idList.iterator();

        Object id;
        while(var7.hasNext()) {
            id = var7.next();

            try {
                Object finalId = id;
                completionService.submit(() -> {
                    return getFuc.apply((T) finalId);
                });
            } catch (Exception var11) {
                log.error(var11.getMessage(), var11);
            }
        }

        var7 = idList.iterator();

        while(var7.hasNext()) {
            id = var7.next();

            try {
                R r = completionService.poll(timeout, TimeUnit.MILLISECONDS).get(timeout, TimeUnit.MILLISECONDS);
                if (r != null) {
                    result.add(r);
                }
            } catch (Exception var10) {
                log.error(var10.getMessage(), var10);
            }
        }

        return result;
    }

    public static <T, R> Map<T, R> multiGetForMap(Collection<T> idList, Function<T, R> getFuc) {
        return multiGetForMap(idList, ThreadExecuter.executor, 1000L, getFuc);
    }

    public static <T, R> Map<T, R> multiGetForMap(Collection<T> idList, ExecutorService executor, Function<T, R> getFuc) {
        return multiGetForMap(idList, executor, 1000L, getFuc);
    }

    public static <T, R> Map<T, R> multiGetForMap(Collection<T> idList, ExecutorService executor, long timeout, Function<T, R> getFuc) {
        Map<T, R> result = new ConcurrentHashMap(idList.size());
        CompletionService<R> completionService = new ExecutorCompletionService(executor);
        Iterator var7 = idList.iterator();

        Object id;
        while(var7.hasNext()) {
            id = var7.next();
            Object finalId = id;
            completionService.submit(() -> {
                R r = getFuc.apply((T) finalId);
                if (r != null) {
                    result.put((T) finalId, r);
                }

                return r;
            });
        }

        var7 = idList.iterator();

        while(var7.hasNext()) {
            id = var7.next();

            try {
                completionService.poll(timeout, TimeUnit.MILLISECONDS).get(timeout, TimeUnit.MILLISECONDS);
            } catch (Exception var10) {
                log.error(var10.getMessage(), var10);
            }
        }

        return result;
    }

    public static <T> List<T> multiBuild(List<T> beanList, Function<T, T> buildFuc) {
        return (List)beanList.parallelStream().filter((t) -> {
            return t != null;
        }).map(buildFuc).collect(Collectors.toList());
    }

    public static <T> T multiBuildObject(Class<T> clazz, long timeout, Supplier<T>... builders) throws IllegalAccessException, InstantiationException {
        T t = clazz.newInstance();
        Field[] fields = clazz.getFields();
        CompletionService<T> completionService = new ExecutorCompletionService(ThreadExecuter.executor);
        Supplier[] var7 = builders;
        int var8 = builders.length;

        int var9;
        for(var9 = 0; var9 < var8; ++var9) {
            Supplier<T> builder = var7[var9];
            completionService.submit(() -> {
                return builder.get();
            });
        }

        var7 = builders;
        var8 = builders.length;

        for(var9 = 0; var9 < var8; ++var9) {
            Supplier var10000 = var7[var9];

            try {
                T r = completionService.poll(timeout, TimeUnit.MILLISECONDS).get(timeout, TimeUnit.MILLISECONDS);
                if (r != null) {
                    Field[] var12 = fields;
                    int var13 = fields.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        Field field = var12[var14];
                        field.setAccessible(true);
                        Object o = field.get(r);
                        if (o != null) {
                            field.set(t, o);
                        }
                    }
                }
            } catch (Exception var17) {
                log.error(var17.getMessage(), var17);
            }
        }

        return t;
    }

    public static <R> List<R> multiExecute(int count, ExecutorService executor, long timeout, Supplier<R> executeFuc) {
        List<R> result = new ArrayList(count);
        CompletionService<R> completionService = new ExecutorCompletionService(executor);

        int i;
        for(i = 0; i < count; ++i) {
            completionService.submit(() -> {
                return executeFuc.get();
            });
        }

        for(i = 0; i < count; ++i) {
            try {
                R r = completionService.poll(timeout, TimeUnit.MILLISECONDS).get(timeout, TimeUnit.MILLISECONDS);
                if (r != null) {
                    result.add(r);
                }
            } catch (Exception var9) {
                log.error(var9.getMessage(), var9);
            }
        }

        return result;
    }

    public static void main(String[] args) {

        System.out.println((38*14)+(0));
        System.out.println((33*16)+(0.9*12)+9.5);
    }
}

